package tk.mybatis.simple.mapper;

import org.apache.ibatis.annotations.*;
import tk.mybatis.simple.model.SysRole;

import java.util.List;

public interface RoleMapper {
    @Select({"select id,role_name roleName, enabled, create_by createBy, create_time createTime ", "from sys_role ", "where id = #{id}"})
    SysRole selectById(Long id);

    /**
     * 上面的 @Select 注解方法也可以写成下面这种形式
     * 测试发现就算使用注解的方式也需要创建一个对应的 mapper XML 文件配置到 MyBatis 的配置文件（mybatis-config.xml 的 mappers 标签处）中
     *
     * @param id
     * @return
     */
    @Select({"select id, role_name roleName, enabled, create_by createBy, create_time createTime from sys_role where id = #{id}"})
    SysRole selectById1(Long id);

    /**
     * XML 中的 resultMap 元素有一个对应的 Java 注解 @Results，使用这个注解来实现属性映射。
     * 这里的 @Result 注解对应着 XML 文件中的 <result> 元素，而参数中写上 id = true 时就对应 <id> 元素。
     *
     * @param id
     * @return
     */
    @Results(id = "roleResultMap", value = {
            @Result(property = "id", column = "id", id = true),
            @Result(property = "roleName", column = "role_name"),
            @Result(property = "enabled", column = "enabled"),
            @Result(property = "createBy", column = "create_by"),
            @Result(property = "createTime", column = "create_time")
    })
    @Select({"select id, role_name, enabled, create_by, create_time from sys_role where id = #{id}"})
    SysRole selectById2(Long id);

    // 引用已存在的 @Results，避免了每个方法需要写 @Results 的问题。注解的参数值就是上面代码中设置的 id 的值，当配合着使用 XML 方式的时候，还可以是 XML 中 <resultMap> 元素
    // 的 id 属性值。
    @ResultMap("roleResultMap")
    @Select("select * from sys_role")
    List<SysRole> selectAll();

    @Insert({"insert into sys_role(id, role_name, enabled, create_by, create_time) ", "values(#{id}, #{roleName}, #{enabled}, #{createBy}, #{createTime, jdbcType=TIMESTAMP})"})
    int insert(SysRole sysRole);

    /**
     * 和上面的 insert 方法相比，insert2 方法中的 SQL 中少了 id 一列，注解多了一个 @Options，我们在这个注解中设置了 useGeneratedKeys 和 keyProperty 属性，用法和 XML 相同，
     * 当需要配置多个列时，这个注解也提供了 keyColumn 属性，可以像 XML 中那样配置使用。
     *
     * @param sysRole
     * @return
     */
    @Insert({"insert into sys_role(role_name, enabled, create_by, create_time) ", "values(#{roleName}, #{enabled}, #{createBy}, #{createTime, jdbcType=TIMESTAMP})"})
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert2(SysRole sysRole);

    @Insert({"insert into sys_role(role_name, enabled, create_by, create_time) ", "values(#{roleName}, #{enabled}, #{createBy}, #{createTime, jdbcType=TIMESTAMP})"})
    // 使用 @SelectKey 注解，以下代码是前面 XML 中配置的 selectKey。
    // <selectKey keyColumn="id" resultType="long" keyProperty="id" order="AFTER">
    //     SELECT LAST_INSERT_ID()
    // </selectKey>
    // 来对比一下，配置属性基本上都是相同的，其中 before 为 false 时功能等同于 order="AFTER",before 为 true 时功能等同于 order="BEFORE"。
    // 在不同的数据库中，order 的配置不同。
    @SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty = "id", resultType = Long.class, before = false)
    int insert3(SysRole sysRole);

    @Update({"update sys_role","set role_name = #{roleName},","enabled = #{enabled}","create_by = #{createBy}","create_time = #{createTime, jdbcType=TIMESTAMP}","where id = #{id}"})
    int updateById(SysRole sysRole);

    @Delete("delete from sys_role where id = #{id}")
    int deleteById(Long id);
}
